iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0

在 Github 部署後每一次都要手動 npm run generatenpm run deploy 才會部署上線,但其實也可設定 GitHub Actions 去自動化部署流程,每次 push 就會自動部署。

參考資料:https://nuxt.com/deploy/github-pages

其他部署方式:

https://ithelp.ithome.com.tw/upload/images/20251006/20178581nZ6uiLJAS9.png

!搞笑了!

Github Pages 只支援靜態檔案,但 project-card 中有些需要私有 repo 的最新更新時間,需要帶上 token 的權限驗證,這不能寫在前端,所以好像不該用 Github Pages 部署QQ 我好不容易部署上線QQ

Vercel 部署步驟

  1. Vercel 註冊一個帳號

  2. Add New Project > Import Git Repository 綁定 github 帳號及匯入 repo

  3. 更改 nuxt.config.ts 設定

    export default defineNuxtConfig({
      app: {
        baseURL: '/',            // 不用 repo 名
        head: {
          link: [{ rel: 'icon', href: '/favicon.ico' }],
        }
      },
      modules: ['@nuxt/image-edge'],
      runtimeConfig: {
        githubToken: process.env.VITE_GITHUB_TOKEN,
        public: {}
      },
      nitro: { preset: 'vercel' }   // 刪掉 nitro.github_pages
    })
    
  4. 更改 package.json 設定

    "scripts": {
      "build": "nuxt build",
      "dev": "nuxt dev",
      "generate": "nuxt generate",
      "preview": "nuxt preview",
      "postinstall": "nuxt prepare"
    },
    
  5. git pull 後 Vercel 會自動部署,可以去該專案的 Vercel 頁面的 Logs 結果

然後就好了!超快超方便,而且不會有吃不到圖片的問題!還可以看到部署紀錄,不用蝦等!推推!

https://ithelp.ithome.com.tw/upload/images/20251006/20178581SG75sihDXR.png
要記得把 token 變數放在 .env 中,且要在 Vercel > Setting > Enviroment Variables 設定 Key 和 Value。
https://ithelp.ithome.com.tw/upload/images/20251006/201785818Hyv7BXYhj.png
改完要在在專案 > Deployment 手動 Redeploy,才會更新上去。


!坑來了!

  • import.meta.env.VITE_*前端 build-time 變數,會被編譯進 bundle。
  • 如果你在前端直接 fetch GitHub API:
    • token 就被寫死在瀏覽器 bundle → 使用者能在 DevTools 看到 → 安全性很差
    • 而且 GitHub API 有時會擋 CORS → 在 Vercel 上 client-side 可能變成 401。

所以要改用 Nuxt Server API Route,讓 token 只存在於 server 端(讀 .env 或 Vercel 的環境變數),前端完全不會知道。

https://ithelp.ithome.com.tw/upload/images/20251006/2017858186UHqhztqK.png

  1. 要在根目錄建立 server/api/github/branch.get.ts ,這邊的取名就是api url 的格式,若是取得就是get,若是編輯可能是patch~
    server/api/github/branch.get.ts/api/github/branch........

  2. 在檔案中寫打api的規則

    // server/api/github/branch.get.ts
    
    import { defineEventHandler, getQuery, createError } from 'h3'
    
    export default defineEventHandler(async (event) => {
      const { repo, branch } = getQuery(event) as { repo?: string; branch?: string }
    
      if (!repo || !branch) {
        throw createError({ statusCode: 400, statusMessage: 'Missing repo or branch' })
      }
    
      const url = `https://api.github.com/repos/${repo}/branches/${branch}`
    
    
      const res = await fetch(url, {
        headers: {
          Accept: 'application/vnd.github+json',
          Authorization: `token ${process.env.VITE_GITHUB_TOKEN}`,
          'User-Agent': 'my-website-2025',
        }
      })
    
      if (!res.ok) {
        throw createError({
          statusCode: res.status,
        })
    
      }
    
      const json = await res.json()
      return {
        repo,
        branch,
        pushAt: json?.commit?.commit?.committer?.date ?? null,
        message: json?.commit?.commit?.message ?? null,
        author: json?.commit?.commit?.committer?.name ?? null,
        html_url: json?.commit?.html_url ?? null
      }
    })
    
  3. 前端呼叫的方式

    $fetch 會對應到 server 資料夾建立的路徑

    const getRepoInfo = async (repo, branch) => {
      try {
        const res = await $fetch(`/api/github/branch?repo=${repo}&branch=${branch}`)
        return res;
      } catch (error) {
        return;
      }
    };
    

    要確保 repo 名稱和 branch 名稱都要對到,才會成功取得資料。


我的錯誤歷程

如果4xx ,可能是哪裡的錯誤?

  • 環境變數有沒有吃到,名稱要和 .env 一樣,vercel 上也要記得設定 3 個環境(Development / Preview / Production)

  • repo. branch 名稱有沒有對到

  • 在終端機用 curl 測試,若有回傳正常的 response 代表 api 沒有問題

    curl
      -H "Authorization: token <你的github_token>"
      -H "User-Agent: test"
      https://api.github.com/repos/<owner>/<repo>/branches/<branch>
    
  • Github api 規定要加上 ‘User-Agent': ''(名稱可以自己取),否則會403

  • 每次更新 nuxt.config.ts.env,就會需要重啟 npm run dev 環境,或重新部署 Redeploy

  • 如果 github api 是用 Classic PAT,Authorization 的前綴要用 token ;如果是用 Fine-grained tokens 前綴要用 Bearer (我是用Classic PAT)

  • Classic PAT 要有 repo scope 才能讀私有 repo;Fine-grained PAT 要勾到目標 repo 並給 Contents: Read (我是用Classic PAT)

我卡了好多天,從打 api 本機404,改到本機200,然後部署上線又404,太多坑了Q


上一篇
Day 22 部署至 GitHub Pages
下一篇
Day 24 網站效能檢查(Lighthouse)+ 改善
系列文
《運用通勤時間打造線上履歷作品集:30 天 Nuxt 自我挑戰》25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言